# Load in data
hires_2019_clean <- read_csv('../clean_data/hires_2019_clean.csv')
Rows: 124446 Columns: 19
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (4): start_station_name, start_station_description, end_station_name, end_station_description
dbl (11): duration, start_station_id, start_station_latitude, start_station_longitude, end_station_id, end_station_l...
date (2): start_date, end_date
time (2): start_time, end_time
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
rain_2019_clean <- read_csv('../clean_data/rain_2019_clean.csv')
Rows: 365 Columns: 2
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
dbl (1): rainfall_mm
date (1): start_date
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(hires_2019_clean)
Rows: 124,446
Columns: 19
$ start_date <date> 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, …
$ start_time <time> 05:58:47, 06:02:13, 06:14:09, 06:25:08, 06:54:31, 07:31:24, 08:47:46, 08:48:06, 09:0…
$ end_date <date> 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, 2019-01-01, …
$ end_time <time> 07:16:14, 07:21:17, 07:21:57, 06:36:22, 06:59:52, 07:42:31, 09:00:57, 09:36:29, 09:3…
$ duration <dbl> 77.43, 79.07, 67.80, 11.23, 5.33, 11.12, 13.18, 48.37, 24.80, 81.05, 47.33, 15.42, 58…
$ start_station_id <dbl> 259, 259, 251, 358, 251, 261, 259, 257, 358, 284, 257, 257, 257, 257, 257, 253, 246, …
$ start_station_name <chr> "St Andrew Square", "St Andrew Square", "Waverley Station", "Leith Walk", "Waverley S…
$ start_station_description <chr> "North East corner", "North East corner", "Platform level near Calton Road Exit", "Le…
$ start_station_latitude <dbl> 55.95475, 55.95475, 55.95264, 55.96504, 55.95264, 55.96093, 55.95475, 55.95700, 55.96…
$ start_station_longitude <dbl> -3.192774, -3.192774, -3.187527, -3.176686, -3.187527, -3.181005, -3.192774, -3.11688…
$ end_station_id <dbl> 285, 285, 285, 284, 261, 265, 246, 344, 257, 257, 284, 257, 225, 256, 256, 246, 247, …
$ end_station_name <chr> "Ocean Terminal", "Ocean Terminal", "Ocean Terminal", "Leith Links", "Brunswick Place…
$ end_station_description <chr> "Debenhams / Puregym entrance", "Debenhams / Puregym entrance", "Debenhams / Puregym …
$ end_station_latitude <dbl> 55.98129, 55.98129, 55.98129, 55.96920, 55.96093, 55.93981, 55.93900, 55.93640, 55.95…
$ end_station_longitude <dbl> -3.176351, -3.176351, -3.176351, -3.166885, -3.181005, -3.182739, -3.173924, -3.19425…
$ rainfall_mm <dbl> 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0…
$ start_elevation <dbl> 76.04, 76.04, 57.10, 20.96, 57.10, 33.11, 76.04, 4.30, 20.96, 15.45, 4.30, 4.30, 4.30…
$ end_elevation <dbl> 7.30, 7.30, 7.30, 15.45, 33.11, 80.45, 88.97, 94.55, 4.30, 4.30, 15.45, 4.30, 53.83, …
$ elevation_diff <dbl> -68.74, -68.74, -49.80, -5.51, -23.99, 47.34, 12.93, 90.25, -16.66, -11.15, 11.15, 0.…
# visualising use by month
hires_2019_clean %>%
mutate(month = month(start_date, label = TRUE), .before = 1) %>%
group_by(month) %>%
summarise(count = n()) %>%
ggplot() +
aes(x = month, y = count) +
geom_col(fill = "#F27F1B") +
geom_text(aes(label = count), vjust = 2, colour = "white", size = 3.5) +
labs(x = "\nMonth",
y = "Number of journeys\n",
title = "Total number of bike journeys by month (2019)",
subtitle = "Total = 124446 journeys\n\n") +
scale_y_discrete(expand = c(0,1), limits = c(0, 5000, 10000, 15000)) +
theme_minimal() +
theme(title = element_text(size = 12),
axis.text = element_text(size = 10),
axis.title.x = element_text(size = 10),
axis.title.y = element_text(size = 10),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "black"))
Mapping out stations
# create smaller dataset for map
map_data <- hires_2019_clean %>%
select(start_station_longitude, start_station_latitude, start_station_id, start_station_name, start_elevation) %>%
distinct(start_station_id, .keep_all = TRUE)
# create custom icon for bike hire stations
bike <- makeIcon("../www/bicycle-outline.png")
# map station data using leaflet app
map_data %>%
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addTiles(providers$CartoDB.Positron) %>%
addMarkers(~start_station_longitude, ~start_station_latitude,
icon = ~bike,
#clusterOptions = markerClusterOptions(),
popup = ~paste0("Station ID: ", start_station_id,
"<br>Name: ", start_station_name,
"<br>Elevation (m): ", start_elevation))
# addCircles(lng = ~start_station_longitude,
# lat = ~start_station_latitude,
# color = "#F27F1B",
# popup = ~paste0("Station ID: ", start_station_id,
# "<br>Name: ", start_station_name,
# "<br>Elevation (m): ", start_elevation))
Most popular stations
# top 10 start and end stations
hires_2019_clean %>%
select(start_station_id, start_station_name, start_station_description, start_elevation) %>%
count(start_station_id, start_station_name, start_station_description, start_elevation) %>%
arrange(desc(n)) %>%
head(10)
hires_2019_clean %>%
select(end_station_id, end_station_name, end_station_description, end_elevation) %>%
count(end_station_id, end_station_name, end_station_description, end_elevation) %>%
arrange(desc(n)) %>%
head(10)


hires_2019_clean %>%
select(start_station_id, end_station_id) %>%
filter(start_station_id == c("248", "259", "265", "289", "257", "262", "249", "247", "171", "183"),
end_station_id == c("262", "257", "250", "265", "248", "358", "259", "183", "171", "258")) %>%
chordDiagram(scale = TRUE)
hires_2019_clean %>%
select(start_station_id, end_station_id) %>%
filter(start_station_id == c("248", "259", "265", "289", "257", "262", "249", "247", "171", "183"),
end_station_id == c("262", "257", "250", "265", "248", "358", "259", "183", "171", "258")) %>%
ggraph(layout = "linear") +
geom_edge_arc(edge_colour = "black", edge_alpha = 0.3, edge_width = 0.2) +
geom_node_point(color = "#F27F1B", size = 10) +
geom_node_text(aes(label = name), repel = FALSE, size = 3, nudge_y = 0, colour = "white") +
labs(title = "Journeys between most popular stations\n\n") +
theme_void() +
theme(title = element_text(size = 12),
legend.position = "none",
plot.margin = unit(rep(1, 4), "cm"))
Journeys based on elevation
68622 downhill journeys 43774 uphill journeys 12050 flat journeys
12050 / 124446 * 100
[1] 9.682915
Journeys based on weather
According to www.statista.com “A rainday is when one millimetre or
more of rain occurs in a day.” Based on this I have classified rainy
days as days where rainfall as recorded by www.power.larc.nasa.gov/ was
equal to or over 1mm in Edinburgh.

Hypothesis Test
# calculate the p-value and compare to α value
p_value <- null_distribution %>%
get_p_value(obs_stat = observed_stat, direction = "left")
Warning: Please be cautious in reporting a p-value of 0. This result is an approximation based on the number of `reps` chosen in the `generate()` step. See `?get_p_value()` for more information.
# hypothesis test
# α = 0.05
# H0 - Rain makes no difference to bike hires
# H1 - Rain has an impact on bike hires
# Type of test is one-sample proportion, right-sided.
#
# p value = 0
#
# The p-value being near to 0 means it is less than α, and so we should reject H0 based on our data. The result is statistically significant in favour of H1, that rain may impact bike hire numbers.
# rain_day <- hires_2019_clean %>%
# group_by(start_date) %>%
# mutate(rain_day = rainfall_mm >= 1) %>%
# select(start_date, rain_day) %>%
# count(start_date, rain_day)
#
# null_distribution <- rain_day %>%
# specify(response = rain_day, success = "TRUE") %>%
# hypothesize(null = "point", p = 0.05) %>%
# generate(reps = 10000, type = "draw") %>%
# calculate(stat = "prop")
#
# obs_stat <- rain_day %>%
# specify(response = rain_day, success = "TRUE") %>%
# calculate(stat = "prop")
#
# null_distribution %>%
# visualise() +
# shade_p_value(direction = "right", obs_stat = obs_stat)
#
# null_distribution %>%
# get_p_value(direction = "right", obs_stat = obs_stat)
# bootstrapped hypothesis
# α = 0.05
# H0 - Rain makes no difference to bike hires
# H1 - Rain has an impact on bike hires
# rain_day_flag <- rain_day %>%
# mutate(rain_day_flag = if_else(rain_day == "TRUE", 1, 0))
#
# null_distribution <- rain_day_flag %>%
# specify(response = rain_day_flag) %>%
# hypothesize(null = "point", mu = 0.05) %>%
# generate(reps = 10000, type = "bootstrap") %>%
# calculate(stat = "mean")
#
# null_distribution %>%
# visualise() +
# shade_p_value(direction = "right", obs_stat = obs_stat)
#
# null_distribution %>%
# get_p_value(direction = "right", obs_stat = obs_stat)
Independence Hypothesis Test On Rainy day data
Does a rainy day have an effect on bike hires
α = 0.05 H0 - Rain makes no difference to bike hires H1 - Rain has an
impact on bike hires
The p-value ≤ α, so I reject the null hypothesis H0 in favour of the
alternative hypothesis H1, that rain may have an effect on bike
hires.
Rainy Days in 2019 = 181 Rainy journeys = 58073 (46.7%) Non rainy
journeys = 66373 (53.3%)
66373 / 124446 * 100
[1] 53.33478
Time of Day analysis
Gym Bunnies - 5am to 7am: 2419 17.54 mins
Morning Commuters - 7am to 9am: 12452 17.87 mins
Day Trippers - 9am to 5pm: 66880 29.75 mins
Homeward Bounders - 5pm to 6.30pm: 14961 23.86 mins
Evening Movers - 6.30pm to 10pm: 16815 23.50 mins
Pub Ponies - 10pm to 5am: 10919 23.07 mins
Average journey time overall is 26.18 minutes
Most popular hour is from 4pm to 5pm 12279 journeys average time
24.27 mins.
hires_2019_clean %>%
select(start_time) %>%
group_by(start_time) %>%
count() %>%
ggplot() +
geom_histogram(aes(start_time), col = "white", fill = "#F27F1B") +
labs(x = "\nTime of Day",
y = "Number of Journeys\n",
title = "Start time of journeys") +
theme_minimal() +
theme(title = element_text(size = 12),
axis.text = element_text(size = 10),
axis.title.x = element_text(size = 10),
axis.title.y = element_text(size = 10),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "black"))
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

hires_2019_clean %>%
mutate(start_hour = hour(start_time), .before = 2) %>%
group_by(start_hour) %>%
count(start_hour) %>%
ggplot() +
#geom_rect(aes(xmin=0, xmax=7, ymin=0, ymax=Inf), fill = "#F27F1B", alpha = 0.1) +
annotate("rect", xmin = 0, xmax = 7, ymin = 0, ymax = Inf, fill = "#FFFB85", alpha = .7) +
annotate("rect", xmin = 7, xmax = 9, ymin = 0, ymax = Inf, fill = "#FFE930", alpha = .6) +
annotate("rect", xmin = 9, xmax = 17, ymin = 0, ymax = Inf, fill = "#F27F1B", alpha = .4) +
annotate("rect", xmin = 17, xmax = 18.5, ymin = 0, ymax = Inf, fill = "#DE6DCC", alpha = .4) +
annotate("rect", xmin = 18.5, xmax = 22, ymin = 0, ymax = Inf, fill = "#9D84F5", alpha = .7) +
annotate("rect", xmin = 22, xmax = 23, ymin = 0, ymax = Inf, fill = "#5A4FF5", alpha = .9) +
geom_point(aes(start_hour, n), color = "#F27F1B") +
geom_line(aes(start_hour, n), color = "#F27F1B", alpha = 0.5) +
labs(x = "\nStart hour",
y = "Number of Journeys\n",
title = "START TIME OF JOURNEYS\n") +
scale_x_discrete(expand = c(0,.5), limits = c(0:23)) +
theme_minimal() +
theme(title = element_text(size = 12, family="Proxima Nova", face = "bold"),
axis.text = element_text(size = 10, family="Proxima Nova", face = "bold", colour = "#8C8C8C"),
axis.title.x = element_text(size = 10, colour = "#8C8C8C"),
axis.title.y = element_text(size = 10, colour = "#8C8C8C"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "#8C8C8C"))
Warning: Continuous limits supplied to discrete scale.
Did you mean `limits = factor(...)` or `scale_*_continuous()`?

# trying a raster image of elevation
ggplot() +
geom_raster(data = new_elevation_raster, aes(x = x, y = y)) +
geom_sf(data = elevation_raster, color = "white") +
coord_sf() +
scale_fill_viridis_c() +
labs(title = " ", x = " ", y = " ", fill = " ")
Error in fortify(data) : object 'new_elevation_raster' not found
LS0tCnRpdGxlOiAiRmluYWwgUHJvamVjdCB3b3JrYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKYGBge3IgaW5jbHVkZT1GQUxTRX0KIyBsb2FkIGxpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShlbGV2YXRyKQpsaWJyYXJ5KHJnZGFsKQpsaWJyYXJ5KGNpcmNsaXplKQpsaWJyYXJ5KGdncmFwaCkKbGlicmFyeShpbmZlcikKbGlicmFyeShzZikKbGlicmFyeShyZ2VvYm91bmRhcmllcykKbGlicmFyeShtYXBkZWNrKQoKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQojIExvYWQgaW4gZGF0YQpoaXJlc18yMDE5X2NsZWFuIDwtIHJlYWRfY3N2KCcuLi9jbGVhbl9kYXRhL2hpcmVzXzIwMTlfY2xlYW4uY3N2JykKcmFpbl8yMDE5X2NsZWFuIDwtIHJlYWRfY3N2KCcuLi9jbGVhbl9kYXRhL3JhaW5fMjAxOV9jbGVhbi5jc3YnKQoKZ2xpbXBzZShoaXJlc18yMDE5X2NsZWFuKQpgYGAKCgoKYGBge3J9CiMgbnVtYmVyIG9mIHN0YXRpb25zIGluIHRvdGFsOiAxNjQKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZGlzdGluY3Qoc3RhcnRfc3RhdGlvbl9pZCkgJT4lIAogIGNvdW50KCkKCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIGRpc3RpbmN0KGVuZF9zdGF0aW9uX2lkKSAlPiUgCiAgY291bnQoKQpgYGAKCgpgYGB7cn0KIyB2aXN1YWxpc2luZyB1c2UgYnkgbW9udGgKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgbXV0YXRlKG1vbnRoID0gbW9udGgoc3RhcnRfZGF0ZSwgbGFiZWwgPSBUUlVFKSwgLmJlZm9yZSA9IDEpICU+JSAKICBncm91cF9ieShtb250aCkgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgZ2dwbG90KCkgKwogIGFlcyh4ID0gbW9udGgsIHkgPSBjb3VudCkgKwogIGdlb21fY29sKGZpbGwgPSAiI0YyN0YxQiIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY291bnQpLCB2anVzdCA9IDIsIGNvbG91ciA9ICJ3aGl0ZSIsIHNpemUgPSAzLjUpICsKICBsYWJzKHggPSAiXG5Nb250aCIsCiAgICAgICB5ID0gIk51bWJlciBvZiBqb3VybmV5c1xuIiwKICAgICAgIHRpdGxlID0gIlRvdGFsIG51bWJlciBvZiBiaWtlIGpvdXJuZXlzIGJ5IG1vbnRoICgyMDE5KSIsCiAgICAgICBzdWJ0aXRsZSA9ICJUb3RhbCA9IDEyNDQ0NiBqb3VybmV5c1xuXG4iKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShleHBhbmQgPSBjKDAsMSksIGxpbWl0cyA9IGMoMCwgNTAwMCwgMTAwMDAsIDE1MDAwKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUodGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkKCmBgYAoKYGBge3J9CiMgdmlzdWFsaXNlIHVzZSBieSBkYXkgb2YgdGhlIHdlZWsKCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIG11dGF0ZShkYXkgPSB3ZGF5KHN0YXJ0X2RhdGUsIGxhYmVsID0gVFJVRSksIC5iZWZvcmUgPSAxKSAlPiUgCiAgZ3JvdXBfYnkoZGF5KSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBkYXksIHkgPSBjb3VudCkgKwogIGdlb21fY29sKGZpbGwgPSAiI0YyN0YxQiIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY291bnQpLCB2anVzdCA9IDIsIGNvbG91ciA9ICJ3aGl0ZSIsIHNpemUgPSAzLjUpICsKICBsYWJzKHggPSAiXG5EYXkgb2Ygd2VlayIsCiAgICAgICB5ID0gIk51bWJlciBvZiBqb3VybmV5c1xuIiwKICAgICAgIHRpdGxlID0gIlRvdGFsIG51bWJlciBvZiBiaWtlIGpvdXJuZXlzIGJ5IGRheSBvZiB3ZWVrICgyMDE5KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGV4cGFuZCA9IGMoMCwxKSwgbGltaXRzID0gYygwLCA1MDAwLCAxMDAwMCwgMTUwMDApKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSh0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKQpgYGAKCgojIyMgTWFwcGluZyBvdXQgc3RhdGlvbnMKCmBgYHtyfQojIGNyZWF0ZSBzbWFsbGVyIGRhdGFzZXQgZm9yIG1hcAptYXBfZGF0YSA8LSBoaXJlc18yMDE5X2NsZWFuICU+JSAKICBzZWxlY3Qoc3RhcnRfc3RhdGlvbl9sb25naXR1ZGUsIHN0YXJ0X3N0YXRpb25fbGF0aXR1ZGUsIHN0YXJ0X3N0YXRpb25faWQsIHN0YXJ0X3N0YXRpb25fbmFtZSwgc3RhcnRfZWxldmF0aW9uKSAlPiUgCiAgZGlzdGluY3Qoc3RhcnRfc3RhdGlvbl9pZCwgLmtlZXBfYWxsID0gVFJVRSkKYGBgCgoKYGBge3J9CgojIGNyZWF0ZSBjdXN0b20gaWNvbiBmb3IgYmlrZSBoaXJlIHN0YXRpb25zCmJpa2UgIDwtICBtYWtlSWNvbigiLi4vd3d3L2JpY3ljbGUtb3V0bGluZS5wbmciKQoKIyBtYXAgc3RhdGlvbiBkYXRhIHVzaW5nIGxlYWZsZXQgYXBwCm1hcF9kYXRhICU+JSAKICBsZWFmbGV0KCkgJT4lIAogIGFkZFByb3ZpZGVyVGlsZXMocHJvdmlkZXJzJENhcnRvREIuUG9zaXRyb24pICU+JSAKICBhZGRUaWxlcyhwcm92aWRlcnMkQ2FydG9EQi5Qb3NpdHJvbikgJT4lCiAgYWRkTWFya2Vycyh+c3RhcnRfc3RhdGlvbl9sb25naXR1ZGUsIH5zdGFydF9zdGF0aW9uX2xhdGl0dWRlLCAKICAgICAgICAgICAgIGljb24gPSB+YmlrZSwKICAgICAgICAgICAgICNjbHVzdGVyT3B0aW9ucyA9IG1hcmtlckNsdXN0ZXJPcHRpb25zKCksCiAgICAgICAgICAgICBwb3B1cCA9IH5wYXN0ZTAoIlN0YXRpb24gSUQ6ICIsIHN0YXJ0X3N0YXRpb25faWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+TmFtZTogIiwgc3RhcnRfc3RhdGlvbl9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkVsZXZhdGlvbiAobSk6ICIsIHN0YXJ0X2VsZXZhdGlvbikpCgogICMgYWRkQ2lyY2xlcyhsbmcgPSB+c3RhcnRfc3RhdGlvbl9sb25naXR1ZGUsCiAgIyAgICAgICAgICAgIGxhdCA9IH5zdGFydF9zdGF0aW9uX2xhdGl0dWRlLAogICMgICAgICAgICAgICBjb2xvciA9ICIjRjI3RjFCIiwKICAjICAgICAgICAgICAgcG9wdXAgPSB+cGFzdGUwKCJTdGF0aW9uIElEOiAiLCBzdGFydF9zdGF0aW9uX2lkLAogICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5OYW1lOiAiLCBzdGFydF9zdGF0aW9uX25hbWUsCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkVsZXZhdGlvbiAobSk6ICIsIHN0YXJ0X2VsZXZhdGlvbikpCmBgYAoKIyMjIE1vc3QgcG9wdWxhciBzdGF0aW9ucwoKCmBgYHtyfQojIHRvcCAxMCBzdGFydCBhbmQgZW5kIHN0YXRpb25zCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIHNlbGVjdChzdGFydF9zdGF0aW9uX2lkLCBzdGFydF9zdGF0aW9uX25hbWUsIHN0YXJ0X3N0YXRpb25fZGVzY3JpcHRpb24sIHN0YXJ0X2VsZXZhdGlvbikgJT4lIAogIGNvdW50KHN0YXJ0X3N0YXRpb25faWQsIHN0YXJ0X3N0YXRpb25fbmFtZSwgc3RhcnRfc3RhdGlvbl9kZXNjcmlwdGlvbiwgc3RhcnRfZWxldmF0aW9uKSAlPiUgCiAgYXJyYW5nZShkZXNjKG4pKSAlPiUgCiAgaGVhZCgxMCkKCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIHNlbGVjdChlbmRfc3RhdGlvbl9pZCwgZW5kX3N0YXRpb25fbmFtZSwgZW5kX3N0YXRpb25fZGVzY3JpcHRpb24sIGVuZF9lbGV2YXRpb24pICU+JSAKICBjb3VudChlbmRfc3RhdGlvbl9pZCwgZW5kX3N0YXRpb25fbmFtZSwgZW5kX3N0YXRpb25fZGVzY3JpcHRpb24sIGVuZF9lbGV2YXRpb24pICU+JSAKICBhcnJhbmdlKG4pICU+JQogIGhlYWQoMTApCmBgYAoKCmBgYHtyfQojIHJvdW5kIHRyaXAgdnMgYSB0byBiIGpvdXJuZXkKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHN0YXJ0X3N0YXRpb25faWQgPT0gZW5kX3N0YXRpb25faWQpICU+JSAKICBjb3VudCgpCgoxMTk0NCAvIDEyNDQ0NiAqIDEwMCAjIDkuNiUgb2Ygam91cm5leXMgd2VyZSByb3VuZCB0cmlwcwoKIyBtb3N0IHBvcHVsYXIgcm91bmQgdHJpcCBzdGF0aW9ucwpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIoc3RhcnRfc3RhdGlvbl9pZCA9PSBlbmRfc3RhdGlvbl9pZCkgJT4lIAogIGNvdW50KHN0YXJ0X3N0YXRpb25faWQpICU+JSAKICBhcnJhbmdlKGRlc2MobikpCgojIHZpc3VhbGlzZSByb3VuZCB0cmlwIHZzIG9uZSB3YXlzCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIG11dGF0ZShyb3VuZF90cmlwcyA9IHN0YXJ0X3N0YXRpb25faWQgPT0gZW5kX3N0YXRpb25faWQpICU+JSAKICBjb3VudChyb3VuZF90cmlwcykgJT4lIAogIGdncGxvdCgpICsKICBhZXMocm91bmRfdHJpcHMsIG4pICsKICBnZW9tX2NvbChmaWxsID0gIiNGMjdGMUIiKSArCiAgbGFicyh4ID0gIlxuT25lIFdheSB2cyBSb3VuZCBUcmlwIiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIGpvdXJuZXlzXG4iLAogICAgICAgdGl0bGUgPSAiT25lIFdheSB2cyBSb3VuZCBUcmlwIGpvdXJuZXlzIHRha2VuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUodGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkKCmBgYAoKCmBgYHtyfQojIG1hcCBtb3N0IHBvcHVsYXIgc3RhdGlvbnMgZGF0YSB1c2luZyBsZWFmbGV0IGFwcAptYXBfZGF0YSAlPiUgCiAgZmlsdGVyKHN0YXJ0X3N0YXRpb25faWQgJWluJSBjKCIyNDgiLCAiMjU5IiwgIjI2NSIsICIyODkiLCAiMjU3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjI0OSIsICIyNDciLCAiMTcxIiwgIjE4MyIsICIyNjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjUwIiwgIjM1OCIsICIyNTgiKSkgJT4lCiAgbGVhZmxldCgpICU+JSAKICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVycyRDYXJ0b0RCLlBvc2l0cm9uKSAlPiUgCiAgYWRkVGlsZXMocHJvdmlkZXJzJENhcnRvREIuUG9zaXRyb24pICU+JQogIGFkZE1hcmtlcnMofnN0YXJ0X3N0YXRpb25fbG9uZ2l0dWRlLCB+c3RhcnRfc3RhdGlvbl9sYXRpdHVkZSwgCiAgICAgICAgICAgICBpY29uID0gfmJpa2UsCiAgICAgICAgICAgICBwb3B1cCA9IH5wYXN0ZTAoIlN0YXRpb24gSUQ6ICIsIHN0YXJ0X3N0YXRpb25faWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5OYW1lOiAiLCBzdGFydF9zdGF0aW9uX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5FbGV2YXRpb24gKG0pOiAiLCBzdGFydF9lbGV2YXRpb24pKQoKYGBgCgpgYGB7cn0KbWFwX2RhdGEgJT4lIAogIGZpbHRlcihzdGFydF9zdGF0aW9uX2lkICVpbiUgYygiMjQ4IiwgIjI1OSIsICIyNjUiLCAiMjg5IiwgIjI1NyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjQ5IiwgIjI0NyIsICIxNzEiLCAiMTgzIiwgIjI2MiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjUwIiwgIjM1OCIsICIyNTgiKSkgJT4lIAogIGdncGxvdChsYWJlbCA9IHN0YXJ0X3N0YXRpb25faWQpICsKICBnZW9tX3BvaW50KGFlcyhzdGFydF9zdGF0aW9uX2lkLCBzdGFydF9lbGV2YXRpb24pKSArCiAgdGhlbWVfYncoKSArCiAgZ2VvbV90ZXh0KGFlcyhzdGFydF9zdGF0aW9uX2lkLCBzdGFydF9lbGV2YXRpb24sIGxhYmVsID0gc3RhcnRfZWxldmF0aW9uLCBoanVzdD0tMC4yLCB2anVzdD0wKSkKCmBgYAoKYGBge3J9CmxpYnJhcnkobWFwZGVjaykKCnNldF90b2tlbigicGsuZXlKMUlqb2lhbUkzTkNJc0ltRWlPaUpqYkRONE5tNTJPR013WjNwbk0yTnhkSGhsTVRoeGFuQTBJbjAuaUZOY09ndVU2cmtVUUVoR3J1cVNCZyIpICAjIyBzZXQgeW91ciBtYXBib3ggdG9rZW4gaGVyZQojc2V0X3Rva2VuKCJway5leUoxSWpvaWFtSTNOQ0lzSW1FaU9pSmpiRE40Tm01Mk9HTXdaM3BuTTJOeGRIaGxNVGh4YW5BMEluMC5pRk5jT2d1VTZya1VRRWhHcnVxU0JnIikgICMjIHNldCB5b3VyIG1hcGJveCB0b2tlbiBoZXJlCgojbWFwZGVja190b2tlbnMoKQoKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCmZpbHRlcihzdGFydF9zdGF0aW9uX2lkICVpbiUgYygiMjQ4IikpICU+JSAKICBuYS5vbWl0KCkgJT4lIAptYXBkZWNrKHN0eWxlID0gbWFwZGVja19zdHlsZSgnZGFyaycpLCBwaXRjaCA9IDQ1LAogICAgICAgIGxvY2F0aW9uID0gYyg1NS45NDIsIC0zLjE5OSkpJT4lCiAgYWRkX2FyYygKICAgICAgbGF5ZXJfaWQgPSAnYXJjX2xheWVyJwogICAgLCBvcmlnaW4gPSBjKCJzdGFydF9zdGF0aW9uX2xvbmdpdHVkZSIsICJzdGFydF9zdGF0aW9uX2xhdGl0dWRlIikKICAgICwgZGVzdGluYXRpb24gPSBjKCJlbmRfc3RhdGlvbl9sb25naXR1ZGUiLCAiZW5kX3N0YXRpb25fbGF0aXR1ZGUiKQogICAgLCBzdHJva2VfZnJvbV9vcGFjaXR5ID0gMTAwCiAgICAsIHN0cm9rZV90b19vcGFjaXR5ID0gMTAwCiAgICAsIHN0cm9rZV93aWR0aCA9IDMKICAgICwgc3Ryb2tlX2Zyb20gPSAiI0YyN0YxQiIKICAgICwgc3Ryb2tlX3RvID0gIiNGMjdGMUIiCiAgICAsIHRvb2x0aXAgPSAiZW5kX3N0YXRpb25fbmFtZSIKICApCgojIjI1OSIsICIyNjUiLCAiMjg5IiwgIjI1NyIsICIyNDkiLCAiMjQ3IiwgIjE3MSIsICIxODMiLCAiMjYyIiwgIjI1MCIsICIzNTgiLCAiMjU4IgpgYGAKCgpgYGB7cn0KaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgc2VsZWN0KHN0YXJ0X3N0YXRpb25faWQsIGVuZF9zdGF0aW9uX2lkKSAlPiUgCiAgZmlsdGVyKHN0YXJ0X3N0YXRpb25faWQgPT0gYygiMjQ4IiwgIjI1OSIsICIyNjUiLCAiMjg5IiwgIjI1NyIsICIyNjIiLCAiMjQ5IiwgIjI0NyIsICIxNzEiLCAiMTgzIiksIAogICAgICAgICBlbmRfc3RhdGlvbl9pZCA9PSBjKCIyNjIiLCAiMjU3IiwgIjI1MCIsICIyNjUiLCAiMjQ4IiwgIjM1OCIsICIyNTkiLCAiMTgzIiwgIjE3MSIsICIyNTgiKSkgJT4lIAogIGNob3JkRGlhZ3JhbShzY2FsZSA9IFRSVUUpCiAgCmBgYAoKYGBge3J9CiMgSm91cm5leXMgZW5kaW5nIGF0IFZpY3RvcmlhIFF1YXkKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGVuZF9zdGF0aW9uX2lkID09ICIyNTAiKSAlPiUgCiAgY291bnQoKQoKIyBKb3VybmV5cyBlbmRpbmcgYXQgVmljdG9yaWEgUXVheSwgYnkgc3RhcnQgc3RhdGlvbgpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIoZW5kX3N0YXRpb25faWQgPT0gIjI1MCIpICU+JSAKICBjb3VudChzdGFydF9zdGF0aW9uX2lkKSAlPiUgCiAgYXJyYW5nZShkZXNjKG4pKQoKIyBKb3VybmV5cyBlbmRpbmcgYXQgR2VvcmdlIFNxdWFyZSwgYnkgc3RhcnQgc3RhdGlvbgpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIoZW5kX3N0YXRpb25faWQgPT0gIjE3MSIpICU+JSAKICBjb3VudChzdGFydF9zdGF0aW9uX2lkKSAlPiUgCiAgYXJyYW5nZShkZXNjKG4pKQoKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHN0YXJ0X3N0YXRpb25faWQgPT0gIjI1OSIpICU+JSAKICBjb3VudChlbmRfc3RhdGlvbl9pZCkgJT4lIAogIGFycmFuZ2UoZGVzYyhuKSkKYGBgCgoKCmBgYHtyfQpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBzZWxlY3Qoc3RhcnRfc3RhdGlvbl9pZCwgZW5kX3N0YXRpb25faWQpICU+JQogIGZpbHRlcihzdGFydF9zdGF0aW9uX2lkID09IGMoIjI0OCIsICIyNTkiLCAiMjY1IiwgIjI4OSIsICIyNTciLCAiMjYyIiwgIjI0OSIsICIyNDciLCAiMTcxIiwgIjE4MyIpLCAKICAgICAgICAgZW5kX3N0YXRpb25faWQgPT0gYygiMjYyIiwgIjI1NyIsICIyNTAiLCAiMjY1IiwgIjI0OCIsICIzNTgiLCAiMjU5IiwgIjE4MyIsICIxNzEiLCAiMjU4IikpICU+JSAKICBnZ3JhcGgobGF5b3V0ID0gImxpbmVhciIpICsgCiAgZ2VvbV9lZGdlX2FyYyhlZGdlX2NvbG91ciA9ICJibGFjayIsIGVkZ2VfYWxwaGEgPSAwLjMsIGVkZ2Vfd2lkdGggPSAwLjIpICsKICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAiI0YyN0YxQiIsIHNpemUgPSAxMCkgKwogIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IEZBTFNFLCBzaXplID0gMywgbnVkZ2VfeSA9IDAsIGNvbG91ciA9ICJ3aGl0ZSIpICsKICBsYWJzKHRpdGxlID0gIkpvdXJuZXlzIGJldHdlZW4gbW9zdCBwb3B1bGFyIHN0YXRpb25zXG5cbiIpICsKICB0aGVtZV92b2lkKCkgKwogIHRoZW1lKHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChyZXAoMSwgNCksICJjbSIpKQpgYGAKCgojIyMgSm91cm5leXMgYmFzZWQgb24gZWxldmF0aW9uCgo2ODYyMiBkb3duaGlsbCBqb3VybmV5cwo0Mzc3NCB1cGhpbGwgam91cm5leXMKMTIwNTAgZmxhdCBqb3VybmV5cwoKYGBge3J9CiMgZG93bmhpbGwgdnMgdXBoaWxsIHZzIGZsYXQgam91cm5leXMKIyBiYXNlZCBvbiBlbGV2YXRpb24gb2Ygc3RhcnQgYW5kIGVuZCBzdGF0aW9ucwoKIyA2ODYyMiBkb3duaGlsbCBqb3VybmV5cyA1NSUKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGVsZXZhdGlvbl9kaWZmIDwgMCkgJT4lIAogIGNvdW50KCkKCjY4NjIyIC8gMTI0NDQ2ICogMTAwCgojIDQzNzc0IHVwaGlsbCBqb3VybmV5cyAzNSUKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGVsZXZhdGlvbl9kaWZmID4gMCkgJT4lIAogIGNvdW50KCkKCjQzNzc0IC8gMTI0NDQ2ICogMTAwCgojIDEyMDUwIGZsYXQgam91cm5leXMgOS43JQpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBmaWx0ZXIoZWxldmF0aW9uX2RpZmYgPT0gMCkgJT4lIAogIGNvdW50KCkKCjEyMDUwIC8gMTI0NDQ2ICogMTAwCmBgYApgYGB7cn0KaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKGVuZF9zdGF0aW9uX2xvbmdpdHVkZSA+PSAtMykKICAKYGBgCgoKCiMjIyBKb3VybmV5cyBiYXNlZCBvbiB3ZWF0aGVyCgpBY2NvcmRpbmcgdG8gd3d3LnN0YXRpc3RhLmNvbSAiQSByYWluZGF5IGlzIHdoZW4gb25lIG1pbGxpbWV0cmUgb3IgbW9yZSBvZiByYWluIG9jY3VycyBpbiBhIGRheS4iIEJhc2VkIG9uIHRoaXMgSSBoYXZlIGNsYXNzaWZpZWQgcmFpbnkgZGF5cyBhcyBkYXlzIHdoZXJlIHJhaW5mYWxsIGFzIHJlY29yZGVkIGJ5IHd3dy5wb3dlci5sYXJjLm5hc2EuZ292LyB3YXMgZXF1YWwgdG8gb3Igb3ZlciAxbW0gaW4gRWRpbmJ1cmdoLgoKCmBgYHtyfQpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBzZWxlY3Qoc3RhcnRfZGF0ZSwgcmFpbmZhbGxfbW0pICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKGFlcyhzdGFydF9kYXRlLCByYWluZmFsbF9tbSksIGNvbCA9ICJibHVlIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGNvbD0iI0YyN0YxQiIpICsKICBsYWJzKHggPSAiXG5EYXRlIiwKICAgICAgIHkgPSAiUmFpbmZhbGwgKG1tKVxuIiwKICAgICAgIHRpdGxlID0gIkVkaW5idXJnaCdzIGRhaWx5IHJhaW5mYWxsIGluIDIwMTkiLAogICAgICAgc3VidGl0bGUgPSAiKE9yYW5nZSBsaW5lIGF0IDFtbSwgYWJvdmUgd2hpY2ggd2UgY2xhc3MgYXMgcmFpbnkgZGF5KVxuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUodGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkKYGBgCgojIyMgSHlwb3RoZXNpcyBUZXN0CgpgYGB7cn0KIyBJbmRlcGVuZGVuY2UgSHlwb3RoZXNpcwojIM6xID0gMC4wNQojIEgwIC0gdXBoaWxsIGpvdXJuZXlzIG1ha2VzIG5vIGRpZmZlcmVuY2UgdG8gYmlrZSBoaXJlcwojIEgxIC0gdXBoaWxsIGpvdXJuZXlzIGhhdmUgYW4gaW1wYWN0IG9uIGJpa2UgaGlyZXMKCiMgb3JnYW5pc2UgdGhlIGRhdGEgc28gSSBoYXZlIGFuIHVwaGlsbCBjb2x1bW4gd2l0aCBhIGxvZ2ljYWwgb3V0cHV0IFRSVUUvRkFMU0UgaWYgdGhlIGVsZXZhdGlvbiBjaGFuZ2Ugd2FzIHBvc2l0aXZlCiMgYWxzbyBjb3VudCB0aGUgbnVtYmVyIG9mIGpvdXJuZXlzIHRoYXQgb2NjdXJyZWQgb24gZWFjaCBkYXkKdXBoaWxsIDwtIGhpcmVzXzIwMTlfY2xlYW4gJT4lCiAgZ3JvdXBfYnkoc3RhcnRfZGF0ZSkgJT4lIAogIG11dGF0ZSh1cGhpbGwgPSBlbGV2YXRpb25fZGlmZiA+IDApICU+JQogIHNlbGVjdChzdGFydF9kYXRlLCB1cGhpbGwpICU+JSAKICBjb3VudChzdGFydF9kYXRlLCB1cGhpbGwpCgojIGNyZWF0ZSBhIG51bGwgZGlzdHJpYnV0aW9uIHBlcm11dGluZyB0aGUgVHJ1ZSBhbmQgRmFsc2UgdmFsdWVzIG9uIHdoZXRoZXIgdGhlIGpvdXJuZXkgd2FzIHVwaGlsbCBvciBub3QKIyBkbyAxMGsgcmVwcyBhbmQgY2hlY2sgdGhlIGRpZmZlcmVuY2UgaW4gbWVhbnMgb2YgdGhlIGdyb3VwcwpudWxsX2Rpc3RyaWJ1dGlvbiA8LSB1cGhpbGwgJT4lIAogIHNwZWNpZnkobiB+IHVwaGlsbCkgJT4lCiAgaHlwb3RoZXNpemUobnVsbCA9ICJpbmRlcGVuZGVuY2UiKSAlPiUgCiAgZ2VuZXJhdGUocmVwcyA9IDEwMDAwLCB0eXBlID0gInBlcm11dGUiKSAlPiUgCiAgY2FsY3VsYXRlKHN0YXQgPSAiZGlmZiBpbiBtZWFucyIsIG9yZGVyID0gYygiVFJVRSIsICJGQUxTRSIpKSAKCiMgY3JlYXRlIGFuIG9ic2VydmVkIHN0YXQKb2JzZXJ2ZWRfc3RhdCA8LSB1cGhpbGwgJT4lIAogIHNwZWNpZnkobiB+IHVwaGlsbCkgJT4lCiAgY2FsY3VsYXRlKHN0YXQgPSAiZGlmZiBpbiBtZWFucyIsIG9yZGVyID0gYygiVFJVRSIsICJGQUxTRSIpKSAKCiMgcGxvdCBvYnNlcnZlZCBzdGF0IG9uIHRoZSBudWxsIGRpc3RyaWJ1dGlvbgpudWxsX2Rpc3RyaWJ1dGlvbiAlPiUKICB2aXN1YWxpc2UoKSArCiAgc2hhZGVfcF92YWx1ZShvYnNfc3RhdCA9IG9ic2VydmVkX3N0YXQsIGRpcmVjdGlvbiA9ICJsZWZ0IikKCiMgY2FsY3VsYXRlIHRoZSBwLXZhbHVlIGFuZCBjb21wYXJlIHRvIM6xIHZhbHVlCnBfdmFsdWUgPC0gbnVsbF9kaXN0cmlidXRpb24gJT4lCiAgZ2V0X3BfdmFsdWUob2JzX3N0YXQgPSBvYnNlcnZlZF9zdGF0LCBkaXJlY3Rpb24gPSAibGVmdCIpCgpwX3ZhbHVlCmBgYAoKCmBgYHtyfQojIGh5cG90aGVzaXMgdGVzdAojIM6xID0gMC4wNQojIEgwIC0gUmFpbiBtYWtlcyBubyBkaWZmZXJlbmNlIHRvIGJpa2UgaGlyZXMKIyBIMSAtIFJhaW4gaGFzIGFuIGltcGFjdCBvbiBiaWtlIGhpcmVzCiMgVHlwZSBvZiB0ZXN0IGlzIG9uZS1zYW1wbGUgcHJvcG9ydGlvbiwgcmlnaHQtc2lkZWQuCiMgCiMgcCB2YWx1ZSA9IDAgCiMgCiMgVGhlIHAtdmFsdWUgYmVpbmcgbmVhciB0byAwIG1lYW5zIGl0IGlzIGxlc3MgdGhhbiDOsSwgYW5kIHNvIHdlIHNob3VsZCByZWplY3QgSDAgYmFzZWQgb24gb3VyIGRhdGEuIFRoZSByZXN1bHQgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBpbiBmYXZvdXIgb2YgSDEsIHRoYXQgcmFpbiBtYXkgaW1wYWN0IGJpa2UgaGlyZSBudW1iZXJzLgoKIyByYWluX2RheSA8LSBoaXJlc18yMDE5X2NsZWFuICU+JQojICAgZ3JvdXBfYnkoc3RhcnRfZGF0ZSkgJT4lIAojICAgbXV0YXRlKHJhaW5fZGF5ID0gcmFpbmZhbGxfbW0gPj0gMSkgJT4lIAojICAgc2VsZWN0KHN0YXJ0X2RhdGUsIHJhaW5fZGF5KSAlPiUgCiMgICBjb3VudChzdGFydF9kYXRlLCByYWluX2RheSkKIyAKIyBudWxsX2Rpc3RyaWJ1dGlvbiA8LSByYWluX2RheSAlPiUKIyAgIHNwZWNpZnkocmVzcG9uc2UgPSByYWluX2RheSwgc3VjY2VzcyA9ICJUUlVFIikgJT4lCiMgICBoeXBvdGhlc2l6ZShudWxsID0gInBvaW50IiwgcCA9IDAuMDUpICU+JQojICAgZ2VuZXJhdGUocmVwcyA9IDEwMDAwLCB0eXBlID0gImRyYXciKSAlPiUKIyAgIGNhbGN1bGF0ZShzdGF0ID0gInByb3AiKQojIAojIG9ic19zdGF0IDwtIHJhaW5fZGF5ICU+JQojICAgc3BlY2lmeShyZXNwb25zZSA9IHJhaW5fZGF5LCBzdWNjZXNzID0gIlRSVUUiKSAlPiUKIyAgIGNhbGN1bGF0ZShzdGF0ID0gInByb3AiKQojIAojIG51bGxfZGlzdHJpYnV0aW9uICU+JQojICAgdmlzdWFsaXNlKCkgKwojICAgc2hhZGVfcF92YWx1ZShkaXJlY3Rpb24gPSAicmlnaHQiLCBvYnNfc3RhdCA9IG9ic19zdGF0KQojIAojIG51bGxfZGlzdHJpYnV0aW9uICU+JQojICAgZ2V0X3BfdmFsdWUoZGlyZWN0aW9uID0gInJpZ2h0Iiwgb2JzX3N0YXQgPSBvYnNfc3RhdCkKCmBgYAoKYGBge3J9CiMgYm9vdHN0cmFwcGVkIGh5cG90aGVzaXMKIyDOsSA9IDAuMDUKIyBIMCAtIFJhaW4gbWFrZXMgbm8gZGlmZmVyZW5jZSB0byBiaWtlIGhpcmVzCiMgSDEgLSBSYWluIGhhcyBhbiBpbXBhY3Qgb24gYmlrZSBoaXJlcwoKIyByYWluX2RheV9mbGFnIDwtIHJhaW5fZGF5ICU+JQojICAgbXV0YXRlKHJhaW5fZGF5X2ZsYWcgPSBpZl9lbHNlKHJhaW5fZGF5ID09ICJUUlVFIiwgMSwgMCkpCiMgCiMgbnVsbF9kaXN0cmlidXRpb24gPC0gcmFpbl9kYXlfZmxhZyAlPiUKIyAgIHNwZWNpZnkocmVzcG9uc2UgPSByYWluX2RheV9mbGFnKSAlPiUKIyAgIGh5cG90aGVzaXplKG51bGwgPSAicG9pbnQiLCBtdSA9IDAuMDUpICU+JQojICAgZ2VuZXJhdGUocmVwcyA9IDEwMDAwLCB0eXBlID0gImJvb3RzdHJhcCIpICU+JQojICAgY2FsY3VsYXRlKHN0YXQgPSAibWVhbiIpCiMgCiMgbnVsbF9kaXN0cmlidXRpb24gJT4lCiMgICB2aXN1YWxpc2UoKSArCiMgICBzaGFkZV9wX3ZhbHVlKGRpcmVjdGlvbiA9ICJyaWdodCIsIG9ic19zdGF0ID0gb2JzX3N0YXQpCiMgCiMgbnVsbF9kaXN0cmlidXRpb24gJT4lCiMgICBnZXRfcF92YWx1ZShkaXJlY3Rpb24gPSAicmlnaHQiLCBvYnNfc3RhdCA9IG9ic19zdGF0KQpgYGAKCiMjIyBJbmRlcGVuZGVuY2UgSHlwb3RoZXNpcyBUZXN0IE9uIFJhaW55IGRheSBkYXRhCgpEb2VzIGEgcmFpbnkgZGF5IGhhdmUgYW4gZWZmZWN0IG9uIGJpa2UgaGlyZXMKCs6xID0gMC4wNQpIMCAtIFJhaW4gbWFrZXMgbm8gZGlmZmVyZW5jZSB0byBiaWtlIGhpcmVzCkgxIC0gUmFpbiBoYXMgYW4gaW1wYWN0IG9uIGJpa2UgaGlyZXMKClRoZSBwLXZhbHVlIOKJpCDOsSwgc28gSSByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBIMCBpbiBmYXZvdXIgb2YgdGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgSDEsIAp0aGF0IHJhaW4gX21heV8gaGF2ZSBhbiBlZmZlY3Qgb24gYmlrZSBoaXJlcy4KCmBgYHtyfQojIEluZGVwZW5kZW5jZSBIeXBvdGhlc2lzCiMgzrEgPSAwLjA1CiMgSDAgLSBSYWluIG1ha2VzIG5vIGRpZmZlcmVuY2UgdG8gYmlrZSBoaXJlcwojIEgxIC0gUmFpbiBoYXMgYW4gaW1wYWN0IG9uIGJpa2UgaGlyZXMKCiMgb3JnYW5pc2UgdGhlIGRhdGEgc28gSSBoYXZlIGEgcmFpbl9kYXkgY29sdW1uIHdpdGggYSBsb2dpY2FsIG91dHB1dCBUUlVFL0ZBTFNFIGlmIGl0IHJhaW5lZCB0aGF0IGRheQojIGFsc28gY291bnQgdGhlIG51bWJlciBvZiBqb3VybmV5cyB0aGF0IG9jY3VycmVkIG9uIGVhY2ggZGF5CnJhaW5fZGF5IDwtIGhpcmVzXzIwMTlfY2xlYW4gJT4lCiAgZ3JvdXBfYnkoc3RhcnRfZGF0ZSkgJT4lIAogIG11dGF0ZShyYWluX2RheSA9IHJhaW5mYWxsX21tID49IDEpICU+JSAKICBzZWxlY3Qoc3RhcnRfZGF0ZSwgcmFpbl9kYXkpICU+JSAKICBjb3VudChzdGFydF9kYXRlLCByYWluX2RheSkKCiMgY3JlYXRlIGEgbnVsbCBkaXN0cmlidXRpb24gcGVybXV0aW5nIHRoZSBUcnVlIGFuZCBGYWxzZSB2YWx1ZXMgb24gd2hldGhlciBpdCByYWluZWQKIyBkbyAxMGsgcmVwcyBhbmQgY2hlY2sgdGhlIGRpZmZlcmVuY2UgaW4gbWVhbnMgb2YgdGhlIGdyb3VwcwpudWxsX2Rpc3RyaWJ1dGlvbiA8LSByYWluX2RheSAlPiUgCiAgc3BlY2lmeShuIH4gcmFpbl9kYXkpICU+JQogIGh5cG90aGVzaXplKG51bGwgPSAiaW5kZXBlbmRlbmNlIikgJT4lIAogIGdlbmVyYXRlKHJlcHMgPSAxMDAwMCwgdHlwZSA9ICJwZXJtdXRlIikgJT4lIAogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoIlRSVUUiLCAiRkFMU0UiKSkgCgojIGNyZWF0ZSBhbiBvYnNlcnZlZCBzdGF0Cm9ic2VydmVkX3N0YXQgPC0gcmFpbl9kYXkgJT4lIAogIHNwZWNpZnkobiB+IHJhaW5fZGF5KSAlPiUKICBjYWxjdWxhdGUoc3RhdCA9ICJkaWZmIGluIG1lYW5zIiwgb3JkZXIgPSBjKCJUUlVFIiwgIkZBTFNFIikpIAoKIyBwbG90IG9ic2VydmVkIHN0YXQgb24gdGhlIG51bGwgZGlzdHJpYnV0aW9uCm51bGxfZGlzdHJpYnV0aW9uICU+JQogIHZpc3VhbGlzZSgpICsKICBzaGFkZV9wX3ZhbHVlKG9ic19zdGF0ID0gb2JzZXJ2ZWRfc3RhdCwgZGlyZWN0aW9uID0gImxlZnQiKQoKIyBjYWxjdWxhdGUgdGhlIHAtdmFsdWUgYW5kIGNvbXBhcmUgdG8gzrEgdmFsdWUKcF92YWx1ZSA8LSBudWxsX2Rpc3RyaWJ1dGlvbiAlPiUKICBnZXRfcF92YWx1ZShvYnNfc3RhdCA9IG9ic2VydmVkX3N0YXQsIGRpcmVjdGlvbiA9ICJsZWZ0IikKCnBfdmFsdWUKCmBgYAoKUmFpbnkgRGF5cyBpbiAyMDE5ID0gMTgxClJhaW55IGpvdXJuZXlzID0gNTgwNzMgKDQ2LjclKQpOb24gcmFpbnkgam91cm5leXMgPSA2NjM3MyAoNTMuMyUpCgpgYGB7cn0KIyBjb3VudCB0aGUgbnVtYmVyIG9mIGRheXMgd2l0aCByYWluZmFsbCBlcXVhbCB0byBvciBvdmVyIDFtbQpyYWluXzIwMTlfY2xlYW4gJT4lIAogIGZpbHRlcihyYWluZmFsbF9tbSA+PSAxKSAlPiUgCiAgY291bnQoKQoKIyBqb3VybmV5cyBiYXNlZCBvbiByYWluZmFsbAojIGJhc2VkIG9uIGRhaWx5IHByZWNpcGl0YXRpb24KaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHJhaW5mYWxsX21tID49IDEpICU+JSAKICBjb3VudCgpCgo1ODA3MyAvIDEyNDQ0NiAqIDEwMAoKaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgZmlsdGVyKHJhaW5mYWxsX21tIDwgMSkgJT4lIAogIGNvdW50KCkKCjY2MzczIC8gMTI0NDQ2ICogMTAwCmBgYAoKCiMjIyBUaW1lIG9mIERheSBhbmFseXNpcwoKR3ltIEJ1bm5pZXMgLSA1YW0gdG8gN2FtOiAgICAgICAgICAgMjQxOSAgIDE3LjU0IG1pbnMgICAKTW9ybmluZyBDb21tdXRlcnMgLSA3YW0gdG8gOWFtOiAgICAgMTI0NTIgIDE3Ljg3IG1pbnMgICAgCkRheSBUcmlwcGVycyAtIDlhbSB0byA1cG06ICAgICAgICAgIDY2ODgwICAyOS43NSBtaW5zICAgIApIb21ld2FyZCBCb3VuZGVycyAtIDVwbSB0byA2LjMwcG06ICAxNDk2MSAgMjMuODYgbWlucyAgICAKRXZlbmluZyBNb3ZlcnMgLSA2LjMwcG0gdG8gMTBwbTogICAgMTY4MTUgIDIzLjUwIG1pbnMgICAgClB1YiBQb25pZXMgLSAxMHBtIHRvIDVhbTogICAgICAgICAgIDEwOTE5ICAyMy4wNyBtaW5zICAgCgpBdmVyYWdlIGpvdXJuZXkgdGltZSBvdmVyYWxsIGlzIDI2LjE4IG1pbnV0ZXMKCk1vc3QgcG9wdWxhciBob3VyIGlzIGZyb20gNHBtIHRvIDVwbSAxMjI3OSBqb3VybmV5cyBhdmVyYWdlIHRpbWUgMjQuMjcgbWlucy4KCmBgYHtyfQojIHB1YiBwb25pZXMgZnJvbSB0aGUgbmlnaHQgYmVmb3JlCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIG11dGF0ZShzdGFydF90aW1lID0gYXMuY2hhcmFjdGVyKHN0YXJ0X3RpbWUpLCBlbmRfdGltZSA9IGFzLmNoYXJhY3RlcihlbmRfdGltZSkpICU+JSAKICBmaWx0ZXIoc3RhcnRfdGltZSA8ICIwNTowMDowMCIgfCBzdGFydF90aW1lID49ICIyMjowMDowMCIpICU+JSAKICBtdXRhdGUobWVhbl9kdXJhdGlvbiA9IHJvdW5kKG1lYW4oZHVyYXRpb24pLCAyKSkgJT4lIAogIGNvdW50KG1lYW5fZHVyYXRpb24pCgojIEd5bSBCdW5uaWVzIC0gYmVmb3JlIDdhbQpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBtdXRhdGUoc3RhcnRfdGltZSA9IGFzLmNoYXJhY3RlcihzdGFydF90aW1lKSwgZW5kX3RpbWUgPSBhcy5jaGFyYWN0ZXIoZW5kX3RpbWUpKSAlPiUgCiAgZmlsdGVyKHN0YXJ0X3RpbWUgPiAiMDU6MDA6MDAiLCBzdGFydF90aW1lIDw9ICIwNzowMDowMCIpICU+JSAKICBtdXRhdGUobWVhbl9kdXJhdGlvbiA9IHJvdW5kKG1lYW4oZHVyYXRpb24pLCAyKSkgJT4lIAogIGNvdW50KG1lYW5fZHVyYXRpb24pCgojIE1vcm5pbmcgQ29tbXV0ZXJzIC0gN2FtIHRvIDlhbQpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBtdXRhdGUoc3RhcnRfdGltZSA9IGFzLmNoYXJhY3RlcihzdGFydF90aW1lKSwgZW5kX3RpbWUgPSBhcy5jaGFyYWN0ZXIoZW5kX3RpbWUpKSAlPiUgCiAgZmlsdGVyKHN0YXJ0X3RpbWUgPiAiMDc6MDA6MDAiLCBzdGFydF90aW1lIDw9ICIwOTowMDowMCIpICU+JSAKICBtdXRhdGUobWVhbl9kdXJhdGlvbiA9IHJvdW5kKG1lYW4oZHVyYXRpb24pLCAyKSkgJT4lIAogIGNvdW50KG1lYW5fZHVyYXRpb24pCgojIERheSBUcmlwcGVycyAtIDlhbSB0byA1cG0KaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgbXV0YXRlKHN0YXJ0X3RpbWUgPSBhcy5jaGFyYWN0ZXIoc3RhcnRfdGltZSksIGVuZF90aW1lID0gYXMuY2hhcmFjdGVyKGVuZF90aW1lKSkgJT4lIAogIGZpbHRlcihzdGFydF90aW1lID4gIjA5OjAwOjAwIiwgc3RhcnRfdGltZSA8ICIxNzowMDowMCIpICU+JSAKICBtdXRhdGUobWVhbl9kdXJhdGlvbiA9IHJvdW5kKG1lYW4oZHVyYXRpb24pLCAyKSkgJT4lIAogIGNvdW50KG1lYW5fZHVyYXRpb24pCgojIEhvbWV3YXJkIEJvdW5kZXJzIC0gNXBtIHRvIDYuMzBwbQpoaXJlc18yMDE5X2NsZWFuICU+JSAKICBtdXRhdGUoc3RhcnRfdGltZSA9IGFzLmNoYXJhY3RlcihzdGFydF90aW1lKSwgZW5kX3RpbWUgPSBhcy5jaGFyYWN0ZXIoZW5kX3RpbWUpKSAlPiUgCiAgZmlsdGVyKHN0YXJ0X3RpbWUgPj0gIjE3OjAwOjAwIiwgc3RhcnRfdGltZSA8PSAiMTg6MzA6MDAiKSAlPiUgCiAgbXV0YXRlKG1lYW5fZHVyYXRpb24gPSByb3VuZChtZWFuKGR1cmF0aW9uKSwgMikpICU+JSAKICBjb3VudChtZWFuX2R1cmF0aW9uKQoKIyBFdmVuaW5nIE1vdmVycyAtIDYuMzBwbSB0byAxMHBtCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIG11dGF0ZShzdGFydF90aW1lID0gYXMuY2hhcmFjdGVyKHN0YXJ0X3RpbWUpLCBlbmRfdGltZSA9IGFzLmNoYXJhY3RlcihlbmRfdGltZSkpICU+JSAKICBmaWx0ZXIoc3RhcnRfdGltZSA+ICIxODozMDowMCIsIHN0YXJ0X3RpbWUgPCAiMjI6MDA6MDAiKSAlPiUgCiAgbXV0YXRlKG1lYW5fZHVyYXRpb24gPSByb3VuZChtZWFuKGR1cmF0aW9uKSwgMikpICU+JSAKICBjb3VudChtZWFuX2R1cmF0aW9uKQoKIyBQdWIgUG9uaWVzIC0gMTBwbSB0byBNaWRuaWdodApoaXJlc18yMDE5X2NsZWFuICU+JSAKICBtdXRhdGUoc3RhcnRfdGltZSA9IGFzLmNoYXJhY3RlcihzdGFydF90aW1lKSwgZW5kX3RpbWUgPSBhcy5jaGFyYWN0ZXIoZW5kX3RpbWUpKSAlPiUgCiAgZmlsdGVyKHN0YXJ0X3RpbWUgPj0gIjIyOjAwOjAwIikgJT4lIAogIG11dGF0ZShtZWFuX2R1cmF0aW9uID0gcm91bmQobWVhbihkdXJhdGlvbiksIDIpKSAlPiUgCiAgY291bnQobWVhbl9kdXJhdGlvbikKCiMgaGlyZXMgYXQgbW9zdCBwb3B1bGFyIHRpbWUgb2YgNHBtCmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIG11dGF0ZShzdGFydF90aW1lID0gYXMuY2hhcmFjdGVyKHN0YXJ0X3RpbWUpLCBlbmRfdGltZSA9IGFzLmNoYXJhY3RlcihlbmRfdGltZSkpICU+JSAKICBmaWx0ZXIoc3RhcnRfdGltZSA+PSAiMTY6MDA6MDAiLCBzdGFydF90aW1lIDwgIjE3OjAwOjAwIikgJT4lIAogIG11dGF0ZShtZWFuX2R1cmF0aW9uID0gcm91bmQobWVhbihkdXJhdGlvbiksIDIpKSAlPiUgCiAgY291bnQobWVhbl9kdXJhdGlvbikKCiMgQXZlcmFnZSBqb3VybmV5IGxlbmd0aApoaXJlc18yMDE5X2NsZWFuICU+JSAKICBtdXRhdGUobWVhbl9kdXJhdGlvbiA9IHJvdW5kKG1lYW4oZHVyYXRpb24pLCAyKSkgJT4lIAogIGNvdW50KG1lYW5fZHVyYXRpb24pCgpgYGAKCgpgYGB7cn0KaGlyZXNfMjAxOV9jbGVhbiAlPiUgCiAgc2VsZWN0KHN0YXJ0X3RpbWUpICU+JQogIGdyb3VwX2J5KHN0YXJ0X3RpbWUpICU+JSAKICBjb3VudCgpICU+JQogIGdncGxvdCgpICsKICBnZW9tX2hpc3RvZ3JhbShhZXMoc3RhcnRfdGltZSksIGNvbCA9ICJ3aGl0ZSIsIGZpbGwgPSAiI0YyN0YxQiIpICsKICBsYWJzKHggPSAiXG5UaW1lIG9mIERheSIsCiAgICAgICB5ID0gIk51bWJlciBvZiBKb3VybmV5c1xuIiwKICAgICAgIHRpdGxlID0gIlN0YXJ0IHRpbWUgb2Ygam91cm5leXMiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSh0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKQpgYGAKYGBge3J9CmhpcmVzXzIwMTlfY2xlYW4gJT4lIAogIG11dGF0ZShzdGFydF9ob3VyID0gaG91cihzdGFydF90aW1lKSwgLmJlZm9yZSA9IDIpICU+JSAKICBncm91cF9ieShzdGFydF9ob3VyKSAlPiUgCiAgY291bnQoc3RhcnRfaG91cikgJT4lIAogIGdncGxvdCgpICsKICAjZ2VvbV9yZWN0KGFlcyh4bWluPTAsIHhtYXg9NywgeW1pbj0wLCB5bWF4PUluZiksIGZpbGwgPSAiI0YyN0YxQiIsIGFscGhhID0gMC4xKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMCwgeG1heCA9IDcsIHltaW4gPSAwLCB5bWF4ID0gSW5mLCBmaWxsID0gIiNGRkZCODUiLCBhbHBoYSA9IC43KSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gNywgeG1heCA9IDksIHltaW4gPSAwLCB5bWF4ID0gSW5mLCBmaWxsID0gIiNGRkU5MzAiLCBhbHBoYSA9IC42KSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gOSwgeG1heCA9IDE3LCB5bWluID0gMCwgeW1heCA9IEluZiwgZmlsbCA9ICIjRjI3RjFCIiwgYWxwaGEgPSAuNCkgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE3LCB4bWF4ID0gMTguNSwgeW1pbiA9IDAsIHltYXggPSBJbmYsIGZpbGwgPSAiI0RFNkRDQyIsIGFscGhhID0gLjQpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxOC41LCB4bWF4ID0gMjIsIHltaW4gPSAwLCB5bWF4ID0gSW5mLCBmaWxsID0gIiM5RDg0RjUiLCBhbHBoYSA9IC43KSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMjIsIHhtYXggPSAyMywgeW1pbiA9IDAsIHltYXggPSBJbmYsIGZpbGwgPSAiIzVBNEZGNSIsIGFscGhhID0gLjkpICsKICBnZW9tX3BvaW50KGFlcyhzdGFydF9ob3VyLCBuKSwgY29sb3IgPSAiI0YyN0YxQiIpICsKICBnZW9tX2xpbmUoYWVzKHN0YXJ0X2hvdXIsIG4pLCBjb2xvciA9ICIjRjI3RjFCIiwgYWxwaGEgPSAwLjUpICsKICAgIGxhYnMoeCA9ICJcblN0YXJ0IGhvdXIiLAogICAgICAgeSA9ICJOdW1iZXIgb2YgSm91cm5leXNcbiIsCiAgICAgICB0aXRsZSA9ICJTVEFSVCBUSU1FIE9GIEpPVVJORVlTXG4iKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShleHBhbmQgPSBjKDAsLjUpLCBsaW1pdHMgPSBjKDA6MjMpKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSh0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhbWlseT0iUHJveGltYSBOb3ZhIiwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFtaWx5PSJQcm94aW1hIE5vdmEiLCBmYWNlID0gImJvbGQiLCBjb2xvdXIgPSAiIzhDOEM4QyIpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG91ciA9ICIjOEM4QzhDIiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3VyID0gIiM4QzhDOEMiKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiIzhDOEM4QyIpKQpgYGAKCgoKYGBge3J9CiMgdHJ5aW5nIGEgcmFzdGVyIGltYWdlIG9mIGVsZXZhdGlvbgpnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IG5ld19lbGV2YXRpb25fcmFzdGVyLCBhZXMoeCA9IHgsIHkgPSB5KSkgKwogIGdlb21fc2YoZGF0YSA9IGVsZXZhdGlvbl9yYXN0ZXIsIGNvbG9yID0gIndoaXRlIikgKwogIGNvb3JkX3NmKCkgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKwogIGxhYnModGl0bGUgPSAiICIsIHggPSAiICIsIHkgPSAiICIsIGZpbGwgPSAiICIpCmBgYAoK